package com.i2works.smartluolong.web.utils;


import com.i2works.smartluolong.utils.base.MsgEnum;
import com.i2works.smartluolong.utils.web.Resubmit;
import com.i2works.smartluolong.web.controller.user.UserAccountController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.UUID;

/**
 * 重复提交拦截器
 *
 * @author koal <koal@vip.qq.com>
 * @date 2017/10/17 16:33
 * <p>
 * 第二种方式
 * //        //访问这个页面的时候,生成token
 * //        request.getSession().setAttribute("reqToken", StrUtil.md5(UUID.randomUUID().toString()));
 * //        request.getSession().setAttribute("userName", StrUtil.randomStr(8));
 * //        request.getSession().setAttribute("password", StrUtil.randomStr(8));
 * //        request.getSession().setAttribute("email", StrUtil.randomStr(8) + "@qq.com");
 * //        request.getSession().setAttribute("phone", "189" + StrUtil.randomInt(8));
 * <p>
 * //            //判断token
 * //            String reqToken = (String) request.getSession(false).getAttribute("reqToken");
 * //            if (StringUtils.isNoneBlank(userLogin.getWebToken(), reqToken)) {
 * //                //如果token对比失败,说明是重复提交的,就跳转到注册页面
 * //                if (!userLogin.getWebToken().equalsIgnoreCase(reqToken)) {
 * //                    return "redirect:/user/register";
 * //                }
 * //                //验证通过,删除token
 * //                request.getSession(false).removeAttribute("reqToken");
 * //            } else {
 * //                redirect.addFlashAttribute(MESSAGE_CODE, MsgEnum.FORM_RESUBMIT_ERROR.getMsg());
 * //                return "redirect:/user/register";
 * //            }
 */


public class ResubmitInterceptor extends HandlerInterceptorAdapter {

    private static final String TOKEN = "token";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Resubmit resubmit = method.getAnnotation(Resubmit.class);
            if (resubmit != null) {
                //判断是添加token的注解
                boolean needSaveSession = resubmit.save();
                if (needSaveSession) {
                    //生成token
                    String token = UUID.randomUUID().toString();
                    request.getSession().setAttribute(TOKEN, token);
//                    System.err.println("初始化生成token：" + token);
                }
                //判断是移除token的注解
                boolean needRemoveSession = resubmit.remove();
                if (needRemoveSession) {
                    boolean repeatSubmit = isRepeatSubmit(request);
                    //删除token
                    request.getSession(false).removeAttribute(TOKEN);
                    //如果对比失败，就跳转
                    if (!repeatSubmit) {
                        response.sendRedirect(request.getRequestURI() + "?" + UserAccountController.MESSAGE_CODE + "=" + MsgEnum.FORM_RESUBMIT_ERROR.getMsg());
                    }
                    return repeatSubmit;
                }
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }


    /**
     * 重复提交检测
     * <p>
     * 条件
     * 1、任意端token 为空
     * 2、服务端token 和 客户端token 对比失败返回false
     */
    private boolean isRepeatSubmit(HttpServletRequest request) {
        //服务端token
        String serverToken = (String) request.getSession(false).getAttribute(TOKEN);
        //客户端token
        String clientToken = request.getParameter(TOKEN);
//        System.err.println("服务端token（直读会话）：" + serverToken);
//        System.err.println("客户端token（生成拉取）：" + clientToken);
        return StringUtils.isNoneBlank(serverToken, clientToken) && serverToken.equals(clientToken);
    }
}
